package com.example.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.sql.Date;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Scanner;

import com.example.silvercare.Coalition;
import com.example.silvercare.R;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import app.database.friendlist.Constants;
import app.database.friendlist.FriendListDB;

public class GetAllFriendsLocation extends ListActivity {
	final int TABLE = 0;
	FriendListDB dba;
	FriendListAdapter adapter;
	ArrayList<Friend> friendlist = new ArrayList<Friend>();
	ArrayList<Friend> returnlist = new ArrayList<Friend>();
	
    SharedPreferences myprefs;
    String myname;
    String myemail;

    int proximity;
    
	final Handler UpdateHandler = new Handler(){
		public void handleMessage(Message msg) {
			switch (msg.what) {      
		             case 1:
		         		adapter=new FriendListAdapter(GetAllFriendsLocation.this,returnlist);
		         		GetAllFriendsLocation.this.setListAdapter(adapter);
		                  break;      
		              }      
		              super.handleMessage(msg);  
		         }    
		     }; 
		     
	private class Friend{
		public String name;
		public String email;
		public String address;
		public Friend(String n, String e, String a){
			name = n;
			email = e;
			address = a;
		}
		
	}

	//query another person's location
	public class MyRunnable1 implements Runnable {
		int index;
		String IpAddress;
		String Port;
		public MyRunnable1(int i) {
		       // store parameter for later user
			index = i;
		}

		public void run() {
			String name = friendlist.get(index).name;
			String email = friendlist.get(index).email;
			String latitude;
			String longitude;
			String address;

			if(getFriendConnectionInfo(email)==0)
			{
				 try {
		                Socket socket = new Socket(IpAddress,Integer.parseInt(Port));
		                //outgoing stream redirect to socket
		                message.Message msg1 = new message.Message();
		                msg1.setServiceType(0);
		                msg1.setContent(myname+"|"+myemail);
		                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
		                oos.writeObject(msg1);
		                
		                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
		                message.Message msg2 = (message.Message) ois.readObject();
		                if(msg2.getContent()!=null)
		                {
			        		latitude = msg2.getContent();
			        		longitude = "null";
			        		address = "null";
			        		//setCoordinates();
			        		//setFingerprint();
			        		if(checkProximity(latitude, longitude))
			        		{
				        		Friend f = new Friend(name, email, "Lat: "+latitude+" Lon: "+longitude+"\nFingerprint: \n"+"Address: ");
				        		returnlist.add(f);
								Message message = new Message();      
								message.what = 1;      
								UpdateHandler.sendMessage(message);   
				        		QueryMapEngine(returnlist.size());
			        		}
			        		//setAddress();
		                	Log.d("Tcp Example", "From server: "+msg2.getContent());
		                }
		                else
		                {
			        		latitude = "rejected";
			        		longitude = "rejected";
			        		address = "rejected";
		                	Log.d("Tcp Example", "From server: "+"null");
		                }
		                //Close connection
		                socket.close();

			        } catch (UnknownHostException e) {
		                // TODO Auto-generated catch block
		                e.printStackTrace();
			        } catch (IOException e) {
		                // TODO Auto-generated catch block
		                e.printStackTrace();
			        } catch (ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
			}
		}

		private boolean checkProximity(String latitude, String longitude) {
			// TODO Auto-generated method stub
			if(proximity==-1)
				return true;
			else
				return false;
			//return true;
		}

		//Request Ip address and port throught Coalition
		private int getFriendConnectionInfo(String email){
			String result = Coalition.getFriendConnectionInfo(email);
			if(result==null || !result.contains("|"))
				return -1;
			int mid = result.indexOf("|");
			String s1 = result.substring(0, mid);
			String s2 = result.substring(mid+1, result.length());
			if(s1 == null || s2 == null)
				return -1;
			IpAddress = s1;
			Port = s2;	
			return 0;
		}
	}

	//query map engine
	public class MyRunnable2 implements Runnable {
		private int index;
		public MyRunnable2(int i) {
			index = i;
		}
		@Override
		public void run() {
			// TODO Auto-generated method stub
			//MapEngineClient client = new MapEngineClient();
			//client.close();
			returnlist.get(index-1).address += "NUS";
			Message message = new Message();      
			message.what = 1;      
			UpdateHandler.sendMessage(message);  
		}
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {	
		// TODO Auto-generated method stub
		dba = new FriendListDB(this);
		dba.open();
		setContentView(R.xml.returnfriendlist);

		super.onCreate(savedInstanceState);
		
		getdata();
		
		proximity = getIntent().getIntExtra("PROXIMITY", -1);
		
		adapter=new FriendListAdapter(this,returnlist);
		this.setListAdapter(adapter);
		
        myprefs = PreferenceManager.getDefaultSharedPreferences(this);
        myname = myprefs.getString("namePref", null);
        myemail = myprefs.getString("emailaddressPref", null);
        
		//Create thread to retrieve location of all friends
		/*for(int i=0; i<friendlist.size(); i++){
			Thread initBkgThread = new Thread(new MyRunnable1(i));
			initBkgThread.start();
		}*/
        Thread initBkgThread = new Thread(new Runnable(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				MapEngineClient mapEngine = new MapEngineClient();
				String content = myname+"|"+myemail+"|";
				if(proximity!=-1)
					content += proximity;
				else
					content += "none";
				String emaillist = "";
				FriendListDB dba = new FriendListDB(GetAllFriendsLocation.this);
				int TABLE = 0;
				dba.open();
				Cursor c = dba.getFriends(TABLE);
				//startManagingCursor(c);
				if(c.moveToFirst()){
					do{
						String name = c.getString(c.getColumnIndex(Constants.FRIEND_NAME));
						String email = c.getString(c.getColumnIndex(Constants.EMAIL_NAME));
						emaillist += "|"+email;
						Friend f = new Friend(name, email, "");
						friendlist.add(f);
						Log.v(name,email);
					}while(c.moveToNext());
				}
				c.close();
				dba.close();
				if(emaillist.contentEquals(""))
						return;
				content += emaillist;
				System.out.println("This is Content "+content);
				String result = mapEngine.processService(3, content);
				
				if(result != null)
				{
					Scanner sc=new Scanner(result).useDelimiter("\\|");
					while(sc.hasNext())
					{
						String name = "";
						String email = sc.next();
						String latitude = sc.next();
						String longitude = sc.next();
						String fingerprintX = sc.next();
						String fingerprintY = sc.next();
						String fingerprintZ = sc.next();
						String address = sc.next();
						for(int i = 0; i<friendlist.size(); i++)
						{
							if(email.equalsIgnoreCase(friendlist.get(i).email))
							{
								name = friendlist.get(i).name;
								break;
							}
						}
						Friend f = new Friend(name, email, "Lat: "+latitude+" Lon: "+longitude+"\nFingerprint: "+
								fingerprintX+","+fingerprintY+","+fingerprintZ+"\n"+"Address: "+address);
						returnlist.add(f);
					}
					
					Message message = new Message();      
					message.what = 1;      
					UpdateHandler.sendMessage(message);   
					
					System.out.println(result);
				}
			}
        	
        });
        initBkgThread.start();

	}

	public void getdata(){
		Cursor c = dba.getFriends(TABLE);
		startManagingCursor(c);
		if(c.moveToFirst()){
			do{
				String name = c.getString(c.getColumnIndex(Constants.FRIEND_NAME));
				String email = c.getString(c.getColumnIndex(Constants.EMAIL_NAME));
				DateFormat dateFormat = DateFormat.getDateTimeInstance();
				String datedata = dateFormat.format(new Date(c.getLong(c.getColumnIndex(Constants.DATE_NAME))).getTime());
				Friend f = new Friend(name, email, datedata);
				friendlist.add(f);
			}while(c.moveToNext());
		}
	}
	
	private class FriendListAdapter extends BaseAdapter {
		private LayoutInflater mInflater;
		private ArrayList<Friend> returnfriendlist;
		public FriendListAdapter(Context context, ArrayList<Friend> friendlist) {
			mInflater = LayoutInflater.from(context);
			returnfriendlist = friendlist;
		}
		

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return returnfriendlist.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return returnfriendlist.get(position);
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			final ViewHolder holder;
			View v  = convertView;
			if((v==null) || (v.getTag()==null)){
				v = mInflater.inflate(R.xml.returnfriendlistrow, null);
				holder = new ViewHolder();
				holder.mName = (TextView)v.findViewById(R.id.returnname);
				holder.mEmail = (TextView)v.findViewById(R.id.returnemail);
				holder.mAddress = (TextView)v.findViewById(R.id.returnaddress);
				v.setTag(holder);
			}else{
				holder = (ViewHolder)v.getTag();
			}
			holder.mfriend = (Friend) getItem(position);
			holder.mName.setText(holder.mfriend.name);
			holder.mEmail.setText(holder.mfriend.email);
			holder.mAddress.setText(holder.mfriend.address);
			v.setTag(holder);
			return v;
		}
		
		public class ViewHolder {
			Friend mfriend;
			TextView mName;
			TextView mEmail;
			TextView mAddress;
		}
	}

	private void QueryMapEngine(int i){
		//sent latitude and longitude to map engine
		Thread initBkgThread = new Thread(new MyRunnable2(i));
		initBkgThread.start();
	}
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		dba.close();
		super.onDestroy();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
	}

	@Override
	protected void onRestart() {
		// TODO Auto-generated method stub
		//this.setListAdapter(adapter);
		super.onRestart();
	}

}